﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace MockupDesigner.AppItems.Commands
{
    public class GroupCommand : ICommand
    {

        public CommandType CommandType
        {
            get { return CommandType.Undoable; }
        }

        private DesignerCanvas designerCanvas;
        internal DesignerItem Group { get; set; }

        internal IList<DesignerItem> Items { get; set; }

        private UngroupCommand ungroupCommand;

        public GroupCommand()
        {
            Items = new List<DesignerItem>();
        }

        public void Execute(object target, params object[] parameters)
        {
            if (!(target is DesignerCanvas))
            {
                throw new InvalidCastException("The target must be a DesignerCanvas");
            }
            this.designerCanvas = (DesignerCanvas)target;

            Redo();
        }

        public void Redo()
        {
            if (Group == null) // firstime that we execute the command
            {
                Items = (from item in this.designerCanvas.SelectionService.CurrentSelection.OfType<DesignerItem>()
                         where item.ParentID == Guid.Empty
                         select item).ToList();

                Group = new DesignerItem();
                Group.IsGroup = true;
            }
            Rect rect = GetBoundingRectangle(Items);
            Group.Width = rect.Width;
            Group.Height = rect.Height;
            Canvas.SetLeft(Group, rect.Left);
            Canvas.SetTop(Group, rect.Top);
            Canvas groupCanvas = new Canvas();
            Group.Content = groupCanvas;
            Canvas.SetZIndex(Group, this.designerCanvas.Children.Count);
            this.designerCanvas.Children.Add(Group);

            foreach (DesignerItem item in Items)
                item.ParentID = Group.ID;

            this.designerCanvas.SelectionService.SelectItem(Group);
            this.designerCanvas.DataContext = Group;
        }

        public static Rect GetBoundingRectangle(IEnumerable<DesignerItem> items)
        {
            double x1 = Double.MaxValue;
            double y1 = Double.MaxValue;
            double x2 = Double.MinValue;
            double y2 = Double.MinValue;

            foreach (DesignerItem item in items)
            {
                x1 = Math.Min(Canvas.GetLeft(item), x1);
                y1 = Math.Min(Canvas.GetTop(item), y1);

                x2 = Math.Max(Canvas.GetLeft(item) + (item.ActualWidth == 0 ? item.Width : item.ActualWidth), x2);
                y2 = Math.Max(Canvas.GetTop(item) + (item.ActualHeight == 0 ? item.Height : item.ActualHeight), y2);
            }

            return new Rect(new Point(x1, y1), new Point(x2, y2));
        }

        public void Undo()
        {
            if (ungroupCommand == null)
            {
                ungroupCommand = new UngroupCommand();
                ungroupCommand.Groups.Add(Group, Items);
            }
            ungroupCommand.Execute(this.designerCanvas, null);
        }

    }
}
